<?php

namespace App\Repositories;

use App\Models\Channel;
use App\Models\ChannelOrder;
use App\Models\ChannelOrderRead;
use App\Models\ItemOrder;
use App\Models\Cooperation;
use App\Models\ChannelVisitDay;
use App\Models\ChannelVisitUser;
use App\Models\ChannelRelayDay;
use App\Models\ChannelRelayUser;
use Illuminate\Support\Facades\DB;
use InfyOm\Generator\Common\BaseRepository as iBaseRepository;

class ChannelRepository extends iBaseRepository
{
    /**
     * @var array
     */
    protected $fieldSearchable = [
        'name',
        'type',
        'country',
        'state_id',
        'state',
        'state_name',
        'county_id',
        'county',
        'county_name',
        'zip_id',
        'zip_code',
        'zip',
        'zip_name',
        'address',
        'linkman_name',
        'linkman_phone',
        'linkman_wechat',
        'linkman_duty',
        'status'
    ];

    /**
     * Configure the Model
     **/
    public function model()
    {
        return Channel::class;
    }

    /**
     * 项目方获取渠道
     */
    public function getChannelForItem($id, $itemId, $request)
    {
        $channel = $this->findWithoutFail($id);

        if ($channel)
        {
            $channel->user_num = ItemOrder::select(['id'])
                ->where('item_id', $itemId)
                ->where('channel_id', $id)
                ->groupBy('wechat_user_id')
                ->get()
                ->count();

            $channel->cooperation = Cooperation::where('channel_id', $id)->where('item_id', $itemId)->first();

            $channel->logo = fileUrl($channel->logo);
            $channel->official_account_qrcode = fileUrl($channel->official_account_qrcode);
        }

        return $channel;
    }

    /**
     * 获取项目方渠道
     */
    public function getChannelsForItem($itemId, $request)
    {
        $type = $request['type'] ?? 'all';
        switch ($type) {
            case 'cooperation':
                $channels = $this->model->select(['channels.id', 'channels.name', 'channels.logo', 'channels.linkman_name', 'channels.linkman_phone', 'channels.linkman_wechat', 'channels.linkman_duty'])
                    ->addSelect(DB::raw('IF(cooperations.id > 0, 1, 0) AS is_cooperation'))
                    ->leftJoin('cooperations', function ($join) use ($itemId) {
                        $join->on('cooperations.channel_id', '=', 'channels.id')->where('cooperations.item_id', $itemId)->where('cooperations.status', '<>', Cooperation::STATUS_DEFAULT);
                    })
                    ->where('cooperations.id', '>', 0)
                    ->orderBy('channels.id', 'desc')
                    ->simplePaginate($request['limit'] ?? 20);
                break;

            case 'not_cooperation':
                $channels = $this->model->select(['channels.id', 'channels.name', 'channels.logo', 'channels.linkman_name', 'channels.linkman_phone', 'channels.linkman_wechat', 'channels.linkman_duty'])
                    ->addSelect(DB::raw('IF(cooperations.id > 0, 1, 0) AS is_cooperation'))
                    ->leftJoin('cooperations', function ($join) use ($itemId) {
                        $join->on('cooperations.channel_id', '=', 'channels.id')->where('cooperations.item_id', $itemId)->where('cooperations.status', '<>', Cooperation::STATUS_DEFAULT);
                    })
                    ->whereNull('cooperations.id')
                    ->orderBy('channels.id', 'desc')
                    ->simplePaginate($request['limit'] ?? 20);
                break;

            default:
                $channels = $this->model->select(['channels.id', 'channels.name', 'channels.logo', 'channels.linkman_name', 'channels.linkman_phone', 'channels.linkman_wechat', 'channels.linkman_duty'])
                    ->addSelect(DB::raw('IF(cooperations.id > 0, 1, 0) AS is_cooperation'))
                    ->leftJoin('cooperations', function ($join) use ($itemId) {
                        $join->on('cooperations.channel_id', '=', 'channels.id')->where('cooperations.item_id', $itemId)->where('cooperations.status', '<>', Cooperation::STATUS_DEFAULT);
                    })
                    ->orderBy('channels.id', 'desc')
                    ->simplePaginate($request['limit'] ?? 20);
                break;
        }

        if ($channels->items())
        {
            $orders = ChannelOrder::select(['channel_id'])
                ->addSelect(DB::raw('MAX(created_at) AS created_at'))
                ->whereIn('channel_id', $channels->pluck('id'))
                ->groupBy('channel_id')
                ->pluck('created_at', 'channel_id');

            foreach ($channels as $key => $val)
            {
                $channels[$key]->user_num = ItemOrder::select(['id'])
                    ->where('item_id', $itemId)
                    ->where('channel_id', $val->id)
                    ->groupBy('wechat_user_id')
                    ->get()
                    ->count();

                $channels[$key]->logo = fileUrl($val->logo);
                $channels[$key]->last_order_time = isset($orders[$val->id]) ? $orders[$val->id]->toDateString() : NULL;
            }
        }

        return $channels;
    }

    /**
     * 获取渠道首页数据
     */
    public function getChannelIndex($id)
    {
        // 预约数
        $index['order_num'] = ChannelOrder::where('channel_id', $id)->count('id');
        // 新预约数
        $index['new_num'] = ChannelOrder::where('channel_id', $id)
            ->whereNotIn('id', function ($query) use ($id) {
                $read = new ChannelOrderRead();
                $query->select('channel_order_id')
                    ->from($read->table)
                    ->where('wechat_user_id', getLoginWxUserId())
                    ->where('channel_id', $id);
            })
            ->count('id');

        $weekRange = getWeekRange();

        // 访问量
        $index['visit_num'] = intval(ChannelVisitDay::where('channel_id', $id)->whereBetween('visit_date', $weekRange)->sum('visit_num'));

        // 传播量
        $index['relay_num'] = intval(ChannelRelayDay::where('channel_id', $id)->whereBetween('relay_date', $weekRange)->sum('relay_num'));

        return $index;
    }

    /**
     * 获取渠道访问量数据(天)
     */
    public function getVisitDays($id)
    {
        $startDay = now()->subDays(30)->toDateString();
        $days = ChannelVisitDay::where('channel_id', $id)->where('visit_date', '>', $startDay)->orderBy('id', 'asc')->limit(30)->pluck('visit_num', 'visit_date')->toArray();
        for ($i = 29; $i > 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            if ( ! isset($days[$date]))
            {
                $days[$date] = 0;
            }
        }

        array_multisort(array_keys($days), SORT_ASC, SORT_STRING, $days);
        return $days;
    }

    /**
     * 获取渠道访问量数据(用户)
     */
    public function getVisitUsers($id, $request)
    {
        $visit = ChannelVisitUser::select(['channel_visit_users.id', 'channel_visit_users.wechat_user_id', 'channel_visit_users.visit_num', 'channel_visit_users.updated_at'])
            ->with('hasWechatUser')
            ->where('channel_visit_users.channel_id', $id)
            ->orderBy('channel_visit_users.visit_num', 'desc')
            ->paginate($request['limit'] ?? 20);

        if ($visit->items())
        {
            $wechatUserIds = $visit->pluck('wechat_user_id');
            $orders = ChannelOrder::select(['wechat_user_id'])
                ->addSelect(DB::raw('MAX(id) AS id'))
                ->where('channel_id', $id)
                ->whereIn('wechat_user_id', $wechatUserIds)
                ->groupBy('wechat_user_id')
                ->limit(count($wechatUserIds))
                ->get()
                ->pluck('id', 'wechat_user_id')
                ->toArray();

            foreach ($visit as $key => $val)
            {
                $val->channel_order_id = $orders[$val->wechat_user_id] ?? 0;
                $visit[$key]['wechat_user'] = $val->hasWechatUser;
                unset($visit[$key]->hasWechatUser);
            }
        }

        return $visit;
    }

    /**
     * 获取渠道传播量数据(天)
     */
    public function getRelayDays($id)
    {
        $startDay = now()->subDays(30)->toDateString();
        $days = ChannelRelayDay::where('channel_id', $id)->where('relay_date', '>', $startDay)->orderBy('id', 'asc')->limit(30)->pluck('relay_num', 'relay_date')->toArray();
        for ($i = 29; $i > 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            if ( ! isset($days[$date]))
            {
                $days[$date] = 0;
            }
        }

        array_multisort(array_keys($days), SORT_ASC, SORT_STRING, $days);
        return $days;
    }

    /**
     * 获取渠道传播量数据(用户)
     */
    public function getRelayUsers($id, $request)
    {
        $relay = ChannelRelayUser::select(['channel_relay_users.id', 'channel_relay_users.wechat_user_id', 'channel_relay_users.relay_num', 'channel_relay_users.read_num', 'channel_relay_users.updated_at'])
            ->with('hasWechatUser')
            ->where('channel_relay_users.channel_id', $id)
            ->orderBy('channel_relay_users.relay_num', 'desc')
            ->paginate($request['limit'] ?? 20);

        if ($relay->items())
        {
            $wechatUserIds = $relay->pluck('wechat_user_id');
            $orders = ChannelOrder::select(['wechat_user_id'])
                ->addSelect(DB::raw('MAX(id) AS id'))
                ->where('channel_id', $id)
                ->whereIn('wechat_user_id', $wechatUserIds)
                ->groupBy('wechat_user_id')
                ->limit(count($wechatUserIds))
                ->get()
                ->pluck('id', 'wechat_user_id')
                ->toArray();

            foreach ($relay as $key => $val)
            {
                $val->channel_order_id = $orders[$val->wechat_user_id] ?? 0;
                $relay[$key]['wechat_user'] = $val->hasWechatUser;
                unset($relay[$key]->hasWechatUser);
            }
        }

        return $relay;
    }
}
